<!doctype html>
<html class="theme-next   use-motion ">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />












  <link href="/vendors/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css"/>




  <link href="//fonts.googleapis.com/css?family=Lato:300,400,700,400italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">



<link href="/vendors/font-awesome/css/font-awesome.min.css?v=4.4.0" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=0.4.5.2" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="generics,java,type Inference," />








  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=0.4.5.2" />






<meta name="description" content="Type InferenceType inference is a Java compiler’s ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applica">
<meta property="og:type" content="article">
<meta property="og:title" content="Generic - Type Inference">
<meta property="og:url" content="https://lechance.github.io/posts/2016/01/24/generic-type-inference/index.html">
<meta property="og:site_name" content="Lechance's Blog">
<meta property="og:description" content="Type InferenceType inference is a Java compiler’s ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applica">
<meta property="og:updated_time" content="2016-08-04T07:17:41.179Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Generic - Type Inference">
<meta name="twitter:description" content="Type InferenceType inference is a Java compiler’s ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applica">



<script type="text/javascript" id="hexo.configuration">
  var CONFIG = {
    scheme: '',
    sidebar: 'hide',
    motion: true
  };
</script>

  <title> Generic - Type Inference | Lechance's Blog </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="en">

  <!--[if lte IE 8]>
  <div style=' clear: both; height: 59px; padding:0 0 0 15px; position: relative;margin:0 auto;'>
    <a href="http://windows.microsoft.com/en-US/internet-explorer/products/ie/home?ocid=ie6_countdown_bannercode">
      <img src="http://7u2nvr.com1.z0.glb.clouddn.com/picouterie.jpg" border="0" height="42" width="820"
           alt="You are using an outdated browser. For a faster, safer browsing experience, upgrade for free today or use other browser ,like chrome firefox safari."
           style='margin-left:auto;margin-right:auto;display: block;'/>
    </a>
  </div>
<![endif]-->
  


<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
          m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  ga('create', 'UA-75174040-1', 'auto');
  ga('send', 'pageview');
</script>


  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "//hm.baidu.com/hm.js?5641a55459d47b98c90f424b8ca53a5a";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>




  <div class="container one-column page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-meta ">
  

  <div class="custom-logo-site-title">
    <a href="/"  class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <span class="site-title">Lechance's Blog</span>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>
  <p class="site-subtitle"></p>
</div>

<div class="site-nav-toggle">
  <button>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
  </button>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu ">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-home fa-fw"></i> <br />
            
            Home
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
              <i class="menu-item-icon fa fa-archive fa-fw"></i> <br />
            
            Archives
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">
            
              <i class="menu-item-icon fa fa-tags fa-fw"></i> <br />
            
            Tags
          </a>
        </li>
      
        
        <li class="menu-item menu-item-links">
          <a href="/links" rel="section">
            
              <i class="menu-item-icon fa fa-link fa-fw"></i> <br />
            
            Links
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about" rel="section">
            
              <i class="menu-item-icon fa fa-user fa-fw"></i> <br />
            
            About
          </a>
        </li>
      
        
        <li class="menu-item menu-item-rss">
          <a href="/atom.xml" rel="section">
            
              <i class="menu-item-icon fa fa-rss fa-fw"></i> <br />
            
            Rss
          </a>
        </li>
      

      
      
    </ul>
  

  
</nav>

 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div id="content" class="content">
          

  <div id="posts" class="posts-expand">
    

  
  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                Generic - Type Inference
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            Posted on
            <time itemprop="dateCreated" datetime="2016-01-24T10:52:35+08:00" content="2016-01-24">
              2016-01-24
            </time>
          </span>

          
            <span class="post-category" >
              &nbsp; | &nbsp; In
              
                <span itemprop="about" itemscope itemtype="https://schema.org/Thing">
                  <a href="/categories/Programming/" itemprop="url" rel="index">
                    <span itemprop="name">Programming</span>
                  </a>
                </span>

                
                

              
            </span>
          

          
            
              <span class="post-comments-count">
                &nbsp; | &nbsp;
                <a href="/posts/2016/01/24/generic-type-inference/#comments" itemprop="discussionUrl">
                  <span class="post-comments-count ds-thread-count" data-thread-key="posts/2016/01/24/generic-type-inference/" itemprop="commentsCount"></span>
                </a>
              </span>
            
          

          
		  
		  
			 &nbsp; | &nbsp;
			 <span id="/posts/2016/01/24/generic-type-inference/"class="leancloud_visitors"  data-flag-title="Generic - Type Inference">
             &nbsp;Views
            </span>
		  
		
        </div>
      </header>
    


    <div class="post-body">

      
      

      
        <span itemprop="articleBody"><h4 id="Type_Inference">Type Inference</h4><p><code>Type inference</code> is a Java compiler’s ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable. The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.</p>
<p>To illustrate this last point, in the following example, inference determines that the second argument being passed to the <code>pick</code> method is of type Serializable:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span> &lt;T&gt; <span class="function">T <span class="title">pick</span><span class="params">(T a1, T a2)</span> </span>&#123; <span class="keyword">return</span> a2; &#125;</span><br><span class="line">Serializable s = pick(<span class="string">"d"</span>, <span class="keyword">new</span> ArrayList&lt;String&gt;());</span><br></pre></td></tr></table></figure>
<h5 id="Type_Inference_and_Generic_Methods">Type Inference and Generic Methods</h5><p>Generic Methods introduced you to type inference, which enables you to invoke a generic method as you would an ordinary method, without specifying a type between angle brackets. Consider the following example, BoxDemo, which requires the Box class:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BoxDemo</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">static</span> &lt;U&gt; <span class="function"><span class="keyword">void</span> <span class="title">addBox</span><span class="params">(U u, </span><br><span class="line">      java.util.List&lt;Box&lt;U&gt;&gt; boxes)</span> </span>&#123;</span><br><span class="line">    Box&lt;U&gt; box = <span class="keyword">new</span> Box&lt;&gt;();</span><br><span class="line">    box.set(u);</span><br><span class="line">    boxes.add(box);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">static</span> &lt;U&gt; <span class="function"><span class="keyword">void</span> <span class="title">outputBoxes</span><span class="params">(java.util.List&lt;Box&lt;U&gt;&gt; boxes)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> counter = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (Box&lt;U&gt; box: boxes) &#123;</span><br><span class="line">      U boxContents = box.get();</span><br><span class="line">      System.out.println(<span class="string">"Box #"</span> + counter + <span class="string">" contains ["</span> +</span><br><span class="line">             boxContents.toString() + <span class="string">"]"</span>);</span><br><span class="line">      counter++;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    java.util.ArrayList&lt;Box&lt;Integer&gt;&gt; listOfIntegerBoxes =</span><br><span class="line">      <span class="keyword">new</span> java.util.ArrayList&lt;&gt;();</span><br><span class="line">    BoxDemo.&lt;Integer&gt;addBox(Integer.valueOf(<span class="number">10</span>), listOfIntegerBoxes);</span><br><span class="line">    BoxDemo.addBox(Integer.valueOf(<span class="number">20</span>), listOfIntegerBoxes);</span><br><span class="line">    BoxDemo.addBox(Integer.valueOf(<span class="number">30</span>), listOfIntegerBoxes);</span><br><span class="line">    BoxDemo.outputBoxes(listOfIntegerBoxes);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>The following is the output from this example:</p>
<p>Box #0 contains [10]<br>Box #1 contains [20]<br>Box #2 contains [30]</p>
<a id="more"></a>
<p>The generic method <code>addBox</code> defines one type parameter named <code>U</code>. Generally, a Java compiler can infer the <code>type parameters</code> of a generic method call. Consequently, in most cases, you do not have to specify them. For example, to invoke the generic method <code>addBox</code>, you can specify the type parameter with a <code>type witness</code> as follows:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">BoxDemo.&lt;Integer&gt;addBox(Integer.valueOf(<span class="number">10</span>), listOfIntegerBoxes);</span><br></pre></td></tr></table></figure>
<p>Alternatively, if you omit the <code>type witness</code>,a Java compiler automatically infers (from the method’s arguments) that the <code>type parameter</code> is Integer:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">BoxDemo.addBox(Integer.valueOf(<span class="number">20</span>), listOfIntegerBoxes);</span><br></pre></td></tr></table></figure>
<h5 id="Type_Inference_and_Instantiation_of_Generic_Classes">Type Inference and Instantiation of Generic Classes</h5><p>You can replace the <code>type arguments</code> required to invoke the constructor of a generic class with an empty set of type parameters (&lt;&gt;) as long as the compiler can infer the type arguments from the context. This pair of <em>angle brackets</em> is informally called the diamond.</p>
<p>For example, consider the following variable declaration:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Map&lt;String, List&lt;String&gt;&gt; myMap = <span class="keyword">new</span> HashMap&lt;String, List&lt;String&gt;&gt;();</span><br></pre></td></tr></table></figure>
<p>You can substitute the <code>parameterized type</code> of the constructor with an empty set of <code>type parameters (&lt;&gt;)</code>:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Map&lt;String, List&lt;String&gt;&gt; myMap = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br></pre></td></tr></table></figure>
<p>Note that to take advantage of type inference during generic class instantiation, you must use the diamond <code>(&lt;&gt;)</code>. In the following example, the compiler generates an unchecked conversion warning because the HashMap() constructor refers to the HashMap raw type, not the <code>Map&lt;String, List&lt;String&gt;&gt;</code>type:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Map&lt;String, List&lt;String&gt;&gt; myMap = <span class="keyword">new</span> HashMap(); <span class="comment">// unchecked conversion warning</span></span><br></pre></td></tr></table></figure>
<h5 id="Type_Inference_and_Generic_Constructors_of_Generic_and_Non-Generic_Classes">Type Inference and Generic Constructors of Generic and Non-Generic Classes</h5><p>Note that constructors can be generic (in other words, declare their own formal type parameters) in both generic and non-generic classes. Consider the following example:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyClass</span>&lt;<span class="title">X</span>&gt; </span>&#123;</span><br><span class="line">  &lt;T&gt; MyClass(T t) &#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>Consider the following instantiation of the class MyClass:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> MyClass&lt;Integer&gt;(<span class="string">""</span>)</span><br></pre></td></tr></table></figure>
<p>This statement creates an instance of the parameterized type <code>MyClass&lt;Integer&gt;</code>; the statement explicitly specifies the type Integer for the formal type parameter, <code>X</code>, of the generic class <code>MyClass&lt;X&gt;</code>. Note that the constructor for this generic class contains a formal type parameter, <code>T</code>. The compiler infers the type String for the formal type parameter, <code>T</code>, of the constructor of this generic class (because the actual parameter of this constructor is a String object).</p>
<p>Compilers from releases prior to Java SE 7 are able to infer the actual type parameters of generic constructors, similar to generic methods. However, compilers in Java SE 7 and later can infer the actual type parameters of the generic class being instantiated if you use the diamond (&lt;&gt;). Consider the following example:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">MyClass&lt;Integer&gt; myObject = <span class="keyword">new</span> MyClass&lt;&gt;(<span class="string">""</span>);</span><br></pre></td></tr></table></figure>
<p>In this example, the compiler infers the type Integer for the formal type parameter, <code>X</code>, of the generic class MyClass<x>. It infers the type String for the formal type parameter, <code>T</code>, of the constructor of this generic class.</x></p>
<p><em>Note: It is important to note that the inference algorithm uses only invocation arguments, target types, and possibly an obvious expected return type to infer types. The inference algorithm does not use results from later in the program.</em></p>
<h5 id="Target_Types">Target Types</h5><p>The Java compiler takes advantage of <code>target typing</code> to infer the type parameters of a generic method invocation. The target type of an expression is the data type that the Java compiler expects depending on where the expression appears. Consider the method <code>Collections.emptyList</code>, which is declared as follows:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span> &lt;T&gt; <span class="function">List&lt;T&gt; <span class="title">emptyList</span><span class="params">()</span></span>;</span><br></pre></td></tr></table></figure>
<p>Consider the following assignment statement:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; listOne = Collections.emptyList();</span><br></pre></td></tr></table></figure>
<p>This statement is expecting an instance of <code>List&lt;String&gt;</code>; this data type is the <code>target type</code>. Because the method <code>emptyList</code> returns a value of type <code>List&lt;T&gt;</code>, the compiler infers that the type argument T must be the value String. This works in both Java SE 7 and 8. Alternatively, you could use a <code>type witness</code> and specify the value of T as follows:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; listOne = Collections.&lt;String&gt;emptyList();</span><br></pre></td></tr></table></figure>
<p>However, this is not necessary in this context. It was necessary in other contexts, though. Consider the following method:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">processStringList</span><span class="params">(List&lt;String&gt; stringList)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// process stringList</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>Suppose you want to invoke the method <code>processStringList</code> with an empty list. In Java SE 7, the following statement does not compile:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">processStringList(Collections.emptyList());</span><br></pre></td></tr></table></figure>
<p>The Java SE 7 compiler generates an error message similar to the following:</p>
<p><code>List&lt;Object&gt; cannot be converted to List&lt;String&gt;</code></p>
<p>The compiler requires a value for the type argument <code>T</code> so it starts with the value Object. Consequently, the invocation of <code>Collections.emptyList</code> returns a value of type List<object>, which is incompatible with the method <code>processStringList</code>. Thus, in Java SE 7, you must specify the value of the value of the type argument as follows:</object></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">processStringList(Collections.&lt;String&gt;emptyList());</span><br></pre></td></tr></table></figure>
<p>This is no longer necessary in Java SE 8. The notion of what is a target type has been expanded to include method arguments, such as the argument to the method <code>processStringList</code>. In this case, <code>processStringList</code> requires an argument of type List<string>. The method <code>Collections.emptyList</code> returns a value of <code>List&lt;T&gt;</code>, so using the target type of <code>List&lt;String&gt;</code>, the compiler infers that the type argument <code>T</code> has a value of String. Thus, in Java SE 8, the following statement compiles:</string></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">processStringList(Collections.emptyList());</span><br></pre></td></tr></table></figure>
</span>
      
    </div>

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/generics/" rel="tag">#generics</a>
          
            <a href="/tags/java/" rel="tag">#java</a>
          
            <a href="/tags/type-Inference/" rel="tag">#type Inference</a>
          
        </div>
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/posts/2016/01/17/design-pattern-builder-pattern/" rel="next" title="Design Pattern - Builder Pattern">
                <i class="fa fa-chevron-left"></i> Design Pattern - Builder Pattern
              </a>
            
          </div>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/posts/2016/02/01/design-pattern-proxy-pattern/" rel="prev" title="Design Pattern - Proxy Pattern">
                Design Pattern - Proxy Pattern <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
        <div class="ds-share flat" data-thread-key="posts/2016/01/24/generic-type-inference/"
     data-title="Generic - Type Inference"
     data-content=""
     data-url="https://lechance.github.io/posts/2016/01/24/generic-type-inference/">
  <div class="ds-share-inline">
    <ul  class="ds-share-icons-16">

      <li data-toggle="ds-share-icons-more"><a class="ds-more" href="javascript:void(0);">分享到：</a></li>
      <li><a class="ds-weibo" href="javascript:void(0);" data-service="weibo">微博</a></li>
      <li><a class="ds-qzone" href="javascript:void(0);" data-service="qzone">QQ空间</a></li>
      <li><a class="ds-qqt" href="javascript:void(0);" data-service="qqt">腾讯微博</a></li>
      <li><a class="ds-wechat" href="javascript:void(0);" data-service="wechat">微信</a></li>

    </ul>
    <div class="ds-share-icons-more">
    </div>
  </div>
</div>
      
    </div>
  </div>


        </div>

        


        
  <div class="comments" id="comments">
    
      <div class="ds-thread" data-thread-key="posts/2016/01/24/generic-type-inference/"
           data-title="Generic - Type Inference" data-url="https://lechance.github.io/posts/2016/01/24/generic-type-inference/">
      </div>
    
  </div>


      </div>

      
        
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            Table Of Contents
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            Overview
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel ">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" src="/upload/image/avatar.png" alt="Lechance Cheung" itemprop="image"/>
          <p class="site-author-name" itemprop="name">Lechance Cheung</p>
        </div>
        <p class="site-description motion-element" itemprop="description">The code to change the world</p>
        <nav class="site-state motion-element">
          <div class="site-state-item site-state-posts">
            <a href="/archives">
              <span class="site-state-item-count">43</span>
              <span class="site-state-item-name">posts</span>
            </a>
          </div>

          <div class="site-state-item site-state-categories">
            
              <span class="site-state-item-count">15</span>
              <span class="site-state-item-name">categories</span>
              
          </div>

          <div class="site-state-item site-state-tags">
            <a href="/tags">
              <span class="site-state-item-count">66</span>
              <span class="site-state-item-name">tags</span>
              </a>
          </div>

        </nav>

        

        <div class="links-of-author motion-element">
          
            
              <span class="links-of-author-item">
                <a href="http://weibo.com/lechance" target="_blank">
                  
                    <i class="fa fa-weibo"></i> Weibo
                  
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://github.com/lechance" target="_blank">
                  
                    <i class="fa fa-globe"></i> Github
                  
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://guides.github.com/features/mastering-markdown/" target="_blank">
                  
                    <i class="fa fa-globe"></i> MD CheatSheet
                  
                </a>
              </span>
            
          
        </div>

        
        
          <div class="cc-license motion-element" itemprop="license">
            <a href="http://creativecommons.org/licenses/by-nc-sa/4.0" class="cc-opacity" target="_blank">
              <img src="/images/cc-by-nc-sa.svg" alt="Creative Commons" />
            </a>
          </div>
        

        <div class="links-of-author motion-element">
          
            <p class="site-author-name">Common Sites</p>
            
              <span class="links-of-author-item">
                <a href="https://developers.google.cn" target="_blank">Google Developers</a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://androidweekly.net/archive" target="_blank">Android Weekly</a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://rxjava.yuxingxin.com" target="_blank">RxJava Essentials</a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://hc.apache.org/index.html" target="_blank">Http Components</a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://simpledeveloper.com" target="_blank">Simple Developer</a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://www.ibm.com/developerworks/library" target="_blank">IBM(Technical Library)</a>
              </span>
            
          
        </div>

      </section>

      
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc-indicator-top post-toc-indicator">
            <i class="fa fa-angle-double-up"></i>
          </div>
          <div class="post-toc">
            
              
            
            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-4"><a class="nav-link" href="#Type_Inference"><span class="nav-number">1.</span> <span class="nav-text">Type Inference</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#Type_Inference_and_Generic_Methods"><span class="nav-number">1.1.</span> <span class="nav-text">Type Inference and Generic Methods</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#Type_Inference_and_Instantiation_of_Generic_Classes"><span class="nav-number">1.2.</span> <span class="nav-text">Type Inference and Instantiation of Generic Classes</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#Type_Inference_and_Generic_Constructors_of_Generic_and_Non-Generic_Classes"><span class="nav-number">1.3.</span> <span class="nav-text">Type Inference and Generic Constructors of Generic and Non-Generic Classes</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#Target_Types"><span class="nav-number">1.4.</span> <span class="nav-text">Target Types</span></a></li></ol></li></ol></div>
            
          </div>
          <div class="post-toc-indicator-bottom post-toc-indicator">
            <i class="fa fa-angle-double-down"></i>
          </div>
        </section>
      

    </div>
  </aside>


      
    </main>

    <footer id="footer" class="footer">
      <div class="google-ad">
	  <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- myblogfootergooglead -->
<ins class="adsbygoogle"
     style="display:inline-block;width:468px;height:60px"
     data-ad-client="ca-pub-6226577131784709"
     data-ad-slot="6824128270"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

      </div>
      <div class="footer-inner">
        <script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
</script>

<div class="copyright" >
  
  &copy;  2015 - 
  <span itemprop="copyrightYear">2017</span>
  <span class="with-love">
    <i class="icon-next-heart fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Lechance Cheung</span>
</div>

<div class="powered-by">
  Powered by <a class="theme-link" href="http://hexo.io">Hexo</a>
</div>

<div class="theme-info">
  Theme -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT
  </a>
</div>

<span id="busuanzi_container_site_pv">
  &nbsp; | &nbsp;PV <span id="busuanzi_value_site_pv"></span> &nbsp;| &nbsp;UV <span id="busuanzi_value_site_uv"></span>
</span>



      </div>
    </footer>

    <div class="back-to-top"></div>
  </div>

  <script type="text/javascript" src="/vendors/jquery/index.js?v=2.1.3"></script>

  
  

  
    

  
    
  

  <script type="text/javascript">
    var duoshuoQuery = {short_name:"lechance"};
    (function() {
      var ds = document.createElement('script');
      ds.type = 'text/javascript';ds.async = true;
      ds.id = 'duoshuo-script';
      ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//lechance.github.io/embed_ua.js';
      ds.charset = 'UTF-8';
      (document.getElementsByTagName('head')[0]
      || document.getElementsByTagName('body')[0]).appendChild(ds);
    })();
  </script>
    
     


    
  

  
  <script type="text/javascript" src="/vendors/fancybox/source/jquery.fancybox.pack.js"></script>
  <script type="text/javascript" src="/js/fancy-box.js?v=0.4.5.2"></script>


  <script type="text/javascript" src="/js/helpers.js?v=0.4.5.2"></script>
  <script type="text/javascript" src="/vendors/velocity/velocity.min.js"></script>
<script type="text/javascript" src="/vendors/velocity/velocity.ui.min.js"></script>

<script type="text/javascript" src="/js/motion.js?v=0.4.5.2" id="motion.global"></script>


  <script type="text/javascript" src="/vendors/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  <script type="text/javascript" src="/vendors/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  
  
<script type="text/javascript" src="/js/bootstrap.scrollspy.js?v=0.4.5.2" id="bootstrap.scrollspy.custom"></script>


<script type="text/javascript" id="sidebar.toc.highlight">
  $(document).ready(function () {
    var tocSelector = '.post-toc';
    var $tocSelector = $(tocSelector);
    var activeCurrentSelector = '.active-current';

    $tocSelector
      .on('activate.bs.scrollspy', function () {
        var $currentActiveElement = $(tocSelector + ' .active').last();

        removeCurrentActiveClass();
        $currentActiveElement.addClass('active-current');

        $tocSelector[0].scrollTop = $currentActiveElement.position().top;
      })
      .on('clear.bs.scrollspy', function () {
        removeCurrentActiveClass();
      });

    function removeCurrentActiveClass () {
      $(tocSelector + ' ' + activeCurrentSelector)
        .removeClass(activeCurrentSelector.substring(1));
    }

    function processTOC () {
      getTOCMaxHeight();
      toggleTOCOverflowIndicators();
    }

    function getTOCMaxHeight () {
      var height = $('.sidebar').height() -
                   $tocSelector.position().top -
                   $('.post-toc-indicator-bottom').height();

      $tocSelector.css('height', height);

      return height;
    }

    function toggleTOCOverflowIndicators () {
      tocOverflowIndicator(
        '.post-toc-indicator-top',
        $tocSelector.scrollTop() > 0 ? 'show' : 'hide'
      );

      tocOverflowIndicator(
        '.post-toc-indicator-bottom',
        $tocSelector.scrollTop() >= $tocSelector.find('ol').height() - $tocSelector.height() ? 'hide' : 'show'
      )
    }

    $(document).on('sidebar.motion.complete', function () {
      processTOC();
    });

    $('body').scrollspy({ target: tocSelector });
    $(window).on('resize', function () {
      if ( $('.sidebar').hasClass('sidebar-active') ) {
        processTOC();
      }
    });

    onScroll($tocSelector);

    function onScroll (element) {
      element.on('mousewheel DOMMouseScroll', function (event) {
          var oe = event.originalEvent;
          var delta = oe.wheelDelta || -oe.detail;

          this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
          event.preventDefault();

          toggleTOCOverflowIndicators();
      });
    }

    function tocOverflowIndicator (indicator, action) {
      var $indicator = $(indicator);
      var opacity = action === 'show' ? 1 : 0;
      $indicator.velocity ?
        $indicator.velocity('stop').velocity({
          opacity: opacity
        }, { duration: 100 }) :
        $indicator.stop().animate({
          opacity: opacity
        }, 100);
    }

  });
</script>

<script type="text/javascript" id="sidebar.nav">
  $(document).ready(function () {
    var html = $('html');
    var TAB_ANIMATE_DURATION = 200;
    var hasVelocity = $.isFunction(html.velocity);

    $('.sidebar-nav li').on('click', function () {
      var item = $(this);
      var activeTabClassName = 'sidebar-nav-active';
      var activePanelClassName = 'sidebar-panel-active';
      if (item.hasClass(activeTabClassName)) {
        return;
      }

      var currentTarget = $('.' + activePanelClassName);
      var target = $('.' + item.data('target'));

      hasVelocity ?
        currentTarget.velocity('transition.slideUpOut', TAB_ANIMATE_DURATION, function () {
          target
            .velocity('stop')
            .velocity('transition.slideDownIn', TAB_ANIMATE_DURATION)
            .addClass(activePanelClassName);
        }) :
        currentTarget.animate({ opacity: 0 }, TAB_ANIMATE_DURATION, function () {
          currentTarget.hide();
          target
            .stop()
            .css({'opacity': 0, 'display': 'block'})
            .animate({ opacity: 1 }, TAB_ANIMATE_DURATION, function () {
              currentTarget.removeClass(activePanelClassName);
              target.addClass(activePanelClassName);
            });
        });

      item.siblings().removeClass(activeTabClassName);
      item.addClass(activeTabClassName);
    });

    $('.post-toc a').on('click', function (e) {
      e.preventDefault();
      var targetSelector = escapeSelector(this.getAttribute('href'));
      var offset = $(targetSelector).offset().top;
      hasVelocity ?
        html.velocity('stop').velocity('scroll', {
          offset: offset  + 'px',
          mobileHA: false
        }) :
        $('html, body').stop().animate({
          scrollTop: offset
        }, 500);
    });

    // Expand sidebar on post detail page by default, when post has a toc.
    motionMiddleWares.sidebar = function () {
      var $tocContent = $('.post-toc-content');
      if (CONFIG.sidebar === 'post') {
        if ($tocContent.length > 0 && $tocContent.html().trim().length > 0) {
          displaySidebar();
        }
      }
    };
  });
</script>



  <script type="text/javascript" src="/js/bootstrap.js"></script>

  
  

  
  
  
  
  	 <!-- custom analytics part create by xiamo -->
<script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"></script>
<script>AV.initialize("cHqcCBDQtcbkltuUTyplEYWJ-gzGzoHsz", "SkioJGixXR48ACpgA0W2lOWd");</script>
<script>
function showTime(Counter) {
	var query = new AV.Query(Counter);
	$(".leancloud_visitors").each(function() {
		var url = $(this).attr("id").trim();
		query.equalTo("url", url);
		query.find({
			success: function(results) {
				if (results.length == 0) {
					var content = '0 ' + $(document.getElementById(url)).text();
					$(document.getElementById(url)).text(content);
					return;
				}
				for (var i = 0; i < results.length; i++) {
					var object = results[i];
					var content = object.get('time') + ' ' + $(document.getElementById(url)).text();
					$(document.getElementById(url)).text(content);
				}
			},
			error: function(object, error) {
				console.log("Error: " + error.code + " " + error.message);
			}
		});

	});
}

function addCount(Counter) {
	var Counter = AV.Object.extend("Counter");
	url = $(".leancloud_visitors").attr('id').trim();
	title = $(".leancloud_visitors").attr('data-flag-title').trim();
	var query = new AV.Query(Counter);
	query.equalTo("url", url);
	query.find({
		success: function(results) {
			if (results.length > 0) {
				var counter = results[0];
				counter.fetchWhenSave(true);
				counter.increment("time");
				counter.save(null, {
					success: function(counter) {
						var content =  counter.get('time') + ' ' + $(document.getElementById(url)).text();
						$(document.getElementById(url)).text(content);
					},
					error: function(counter, error) {
						console.log('Failed to save Visitor num, with error message: ' + error.message);
					}
				});
			} else {
				var newcounter = new Counter();
				newcounter.set("title", title);
				newcounter.set("url", url);
				newcounter.set("time", 1);
				newcounter.save(null, {
					success: function(newcounter) {
					    console.log("newcounter.get('time')="+newcounter.get('time'));
						var content = newcounter.get('time') + ' ' + $(document.getElementById(url)).text();
						$(document.getElementById(url)).text(content);
					},
					error: function(newcounter, error) {
						console.log('Failed to create');
					}
				});
			}
		},
		error: function(error) {
			console.log('Error:' + error.code + " " + error.message);
		}
	});
}
$(function() {
	var Counter = AV.Object.extend("Counter");
	if ($('.leancloud_visitors').length == 1) {
		addCount(Counter);
	} else if ($('.post-title-link').length > 1) {
		showTime(Counter);
	}
}); 
</script>
  
  
<!-- mathjax config similar to math.stackexchange -->

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    tex2jax: {
      inlineMath: [ ['$','$'], ["\\(","\\)"] ],
      processEscapes: true
    }
  });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      tex2jax: {
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
      }
    });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>

<script type="text/javascript" src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
</body>
</html>
